package com.csii.activiti.server.core.service.impl;

import com.csii.activiti.server.core.entity.ActFlowNode;
import com.csii.activiti.server.core.entity.ActFlowVariable;
import com.csii.activiti.server.core.exception.VariableTypeDuplicateException;
import com.csii.activiti.server.core.service.FlowVariableService;
import com.csii.activiti.server.core.variable.discover.ActVariableProcessorDiscover;
import org.activiti.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class FlowVariableServiceImpl implements FlowVariableService {

    private List<ActFlowVariable> flowVariables;

    private Map<String, ActVariableProcessorDiscover> variableTypeAndVariableDiscover;

    @Autowired
    private List<ActVariableProcessorDiscover> variableDiscovers;

    @PostConstruct
    private void initVariable(){
        checkVariableTypeDuplicate(variableDiscovers);
        flowVariables = variableDiscovers.stream().map(item -> new ActFlowVariable(item.getVariableName(), item.getVariableType(), item.needManyPeopleReview(), item.needEmptyProcessing(), item.order())).sorted(Comparator.comparing(ActFlowVariable::getOrder)).collect(Collectors.toList());
        variableTypeAndVariableDiscover = variableDiscovers.stream().collect(Collectors.toMap(ActVariableProcessorDiscover::getVariableType, item -> item));
    }


    private void checkVariableTypeDuplicate(List<ActVariableProcessorDiscover> variableDiscovers){
        Set<String> checkList = new HashSet<>();
        for (ActVariableProcessorDiscover variableDiscover : variableDiscovers) {
            if (checkList.contains(variableDiscover.getVariableType())){
                throw new VariableTypeDuplicateException("流程变量类型重复");
            }
            checkList.add(variableDiscover.getVariableType());
        }
    }


    @Override
    public List<ActFlowVariable> queryList() {
        return flowVariables;
    }

    @Override
    public Set<String> queryVariableApprovalUsername(String variableType, ActFlowNode actFlowNode, String executionId, ExecutionEntityImpl processInstance) {
        ActVariableProcessorDiscover actVariableProcessorDiscover = variableTypeAndVariableDiscover.get(variableType);
        if (actVariableProcessorDiscover != null){
            return actVariableProcessorDiscover.getUsernames(actFlowNode, executionId, processInstance);
        }
        return null;
    }
}
